<!--
  弹出框组件   zls-2022/2/10
      Attributes
          1、show             是否显示弹框（默认false不显示）
          2、position         弹出方向left、top、right、bottom、center（默认从中间弹出center）
          3、width            宽度(仅在position值为'center'时生效，一般情况下无需设置)
          4、height           高度(仅在position值为'center'时生效，一般情况下无需设置)
          5、round            是否为圆角（默认是true）
          6、zIndex           显示层级(默认为8889，一般情况下不会使用，只有弹框里嵌套弹框时，才需要传递)

      Events
          1、close            关闭弹框函数

      Slot
          开发者自定义内容，必填项

      Demo==>
          <z-popup :show="show" @close="show = false">
            <div class="popup-content">
              <div>请开始你的表演</div>
            </div>
          </z-popup>

          import { ref } from 'vue'
          const show = ref<boolean>(false)
-->
<template>
  <teleport to="body">
    <div class="z-popup">
      <z-mask :show="show" :zIndex="zIndex - 1" @close="close"></z-mask>
      <div :class="['scrollbar', 'z-popup-content', popupClass, { show: show }]" :style="[popupStyle]" v-dragModal>
        <slot></slot>
      </div>
    </div>
  </teleport>
</template>

<script lang="ts" setup>
import { computed } from 'vue'
const emit = defineEmits(['close'])
const props = defineProps({
  show: {
    type: Boolean,
    default: false
  },
  position: {
    type: String,
    default: 'center'
  },
  width: {
    type: [String, Number],
    default: 'auto'
  },
  height: {
    type: [String, Number],
    default: 'auto'
  },
  round: {
    type: Boolean,
    default: true
  },
  zIndex: {
    type: Number,
    default: 8889
  }
})
// 设置五个方向的圆角
const roundObj = {
  left: {
    'border-top-right-radius': '5px',
    'border-bottom-right-radius': '5px'
  },
  right: {
    'border-top-left-radius': '5px',
    'border-bottom-left-radius': '5px'
  },
  bottom: {
    'border-top-left-radius': '5px',
    'border-top-right-radius': '5px'
  },
  top: {
    'border-bottom-right-radius': '5px',
    'border-bottom-left-radius': '5px'
  },
  center: {
    'border-radius': '5px'
  }
}

// 设置每个方向的类名
const popupClass = computed(() => 'z-popup-content-' + props.position)

// 根据弹出方向，添加弹框最终出现的样式
const popupStyle = computed(() => {
  let obj: any = {}
  if (props.show) {
    obj = props.round ? roundObj[props.position] : { 'border-radius': 0 }
    obj['z-index'] = props.zIndex
    if (props.position === 'center') {
      obj.opacity = 1
      obj.visibility = 'visible'
      obj.width = typeof props.width === 'number' ? props.width + 'px' : props.width
      obj.height = typeof props.height === 'number' ? props.height + 'px' : props.height
    } else {
      obj.transform = 'translate(0, 0)'
    }
  } else {
    if (props.position === 'center') {
      obj.opacity = 0
      obj.visibility = 'hidden'
      obj.width = typeof props.width === 'number' ? props.width + 'px' : props.width
      obj.height = typeof props.height === 'number' ? props.height + 'px' : props.height
    }
  }
  return obj
})

function close() {
  emit('close')
}

// 自定义局部指令：拖拽（当popup弹框组件的slot插槽内容从中间弹出 且 类名为z-modal-main-title，即可有拖拽效果！！！）
const VDragModal = {
  mounted(el: any, binding: any, vnode: any, prevVnode: any) {
    if (binding.instance.position !== 'center') return
    const titleEl = el.querySelector('.z-modal-main-title')
    if (!titleEl) return
    titleEl.onmousedown = (e: any) => {
      const disX = e.clientX - el.offsetLeft
      const disY = e.clientY - el.offsetTop
      document.onmousemove = e => {
        let L = e.clientX - disX
        const T = e.clientY - disY
        if (binding.modifiers.limit) {
          if (L < 0) {
            L = 0
          }
        }
        el.style.left = L + 'px'
        el.style.top = T + 'px'
      }
      titleEl.onmouseup = () => {
        document.onmousemove = null
      }
    }
  }
}
</script>
<script lang="ts">
export default {
  name: 'z-popup'
}
</script>

<style scoped lang="scss">
.z-popup {
  &-content {
    position: fixed;
    background-color: #fff;
    box-shadow: 0 0 15px #fff;
    display: flex;
    flex-direction: column;
    transition: opacity 0.3s, visibility 0.3s, transform 0.3s;
    // overflow-y: auto;
  }
  // 从左边弹出
  &-content-left {
    min-width: 5%;
    max-width: 80%;
    height: 100%;
    left: 0;
    top: 0;
    transform: translate(-120%, 0);
  }
  // 从右边弹出
  &-content-right {
    min-width: 5%;
    max-width: 80%;
    height: 100%;
    right: 0;
    top: 0;
    transform: translate(120%, 0);
  }
  // 从下边弹出
  &-content-bottom {
    width: 100%;
    min-height: 20%;
    max-height: 80%;
    left: 0;
    bottom: 0;
    transform: translate(0, 120%);
  }
  // 从上边弹出
  &-content-top {
    width: 100%;
    min-height: 20%;
    max-height: 80%;
    left: 0;
    top: 0;
    transform: translate(0, -120%);
  }
  // 从中间弹出
  &-content-center {
    max-width: 80%;
    min-height: 15%;
    max-height: 90%;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    opacity: 0;
    visibility: hidden;
  }
}
</style>
